<template>
    <div class="dom-to-img">
        <div class="dti-card" @click="domToImg">
            <img
                src="https://p.qqan.com/up/2022-8/2022815141509020.jpg"
                alt=""
            />
            <div class="dti-title">这是标题呀</div>
            <div class="dti-content">这下面可及时描述信息了</div>
        </div>
    </div>
</template>
<script setup lang="ts">
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.style.position = 'fixed'
canvas.style.left = '10%'
canvas.style.top = '10%'
canvas.style.border = '1px solid red'
document.body.appendChild(canvas)
const draw = function (img: HTMLImageElement) {
    if (!ctx) return

    const width = img.width as number
    const height = img.height as number
    // canvas绘制
    canvas.width = width
    canvas.height = height
    // 画布清除
    ctx.clearRect(0, 0, width, height)
    // 绘制图片到canvas
    ctx.drawImage(img, 0, 0)
}
const img = new Image()
img.onload = () => {
    if (!ctx) return
    draw(img)
    downLoad()
}
const downLoad = () => {
    const url = canvas.toDataURL()
    const a = document.createElement('a')
    a.setAttribute('download', 'myimg.png')
    a.type = 'image/png'
    a.style.display = 'none'
    a.href = url
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
}
const domToSvg = (dom: HTMLElement | HTMLImageElement) => {
    if (!dom) {
        return this
    }
    // 复制DOM节点
    var cloneDom = dom.cloneNode(true) as HTMLElement | HTMLImageElement
    cloneDom.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')
    cloneDom.classList.remove('outline')

    // 如果有图片，变成base64
    var imgDom: HTMLImageElement | null = null
    if (cloneDom.tagName.toLowerCase() == 'img') {
        imgDom = cloneDom as HTMLImageElement
    } else {
        // 这里就假设一个图片，多图自己遍历转换下就好了
        imgDom = cloneDom.querySelector('img')
    }

    if (imgDom) {
        draw(imgDom)
        imgDom.src = canvas.toDataURL()
    }

    var htmlSvg =
        'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="' +
        dom.offsetWidth +
        '" height="' +
        dom.offsetHeight +
        '"><foreignObject x="0" y="0" width="100%" height="100%">' +
        new XMLSerializer().serializeToString(cloneDom) +
        document.querySelector('style')?.outerHTML +
        '</foreignObject></svg>'

    htmlSvg = htmlSvg.replace(/\n/g, '').replace(/\t/g, '').replace(/#/g, '%23')

    // 图片地址显示为DOM转换的svg
    img.src = htmlSvg

    return this
}
const domToImg = (payload: MouseEvent) => {
    console.log('click', payload)

    domToSvg(payload.target as HTMLElement)
}
</script>
<style lang="scss" scoped>
.dom-to-img {
    .dti-card {
        width: 600px;
        height: 600px;
        border: 1px solid rgba(20, 20, 20, 0.3);
        border-radius: 20px;
        overflow-y: hidden;
        img {
            width: 100%;
            height: 400px;
        }
        .dti-title {
            margin-top: 6px;
            font-size: 26px;
            font-weight: 600;
            text-shadow: 4px 4px 4px rgba(20, 20, 20, 0.3);
        }
        .dti-content {
            margin-top: 4px;
        }
    }
}
</style>
